#include "delaywidget.h"
#include "dm/dmdef.h"
#include <QDebug>




DelayWidget::DelayWidget(const uint8_t channel, const uint8_t &sample, const uint16_t &max, QWidget *parent)
    : AGroupBox{tr(LABEL_DELAY), parent}
    , m_channel{channel}
    , m_sample{sample}
{
    slider = new ASlider(this);
    timeSpinBox = new ADoubleSpinBox(this);
    meterSpinBox = new ADoubleSpinBox(this);
    footSpinBox = new ADoubleSpinBox(this);

    auto layout = new QVBoxLayout(this);
    layout->addWidget(slider, 0, Qt::AlignHCenter);
    layout->addWidget(timeSpinBox, 0, Qt::AlignHCenter);
    layout->addWidget(meterSpinBox, 0, Qt::AlignHCenter);
    layout->addWidget(footSpinBox, 0, Qt::AlignHCenter);
    layout->setSpacing(15 * ratio());

    slider->setRange(DELAY_MIN * m_sample, max * m_sample);

    timeSpinBox->setRange(DELAY_MIN, max);
    timeSpinBox->setSingleStep(1.0 / m_sample);
    timeSpinBox->setDecimals(DELAY_DECIMAL);
    timeSpinBox->setSuffix(tr(LABEL_TIME_MS_UNIT));

    meterSpinBox->setRange(DELAY_MIN * DELAY_METER_RATIO, max * DELAY_METER_RATIO);
    meterSpinBox->setSingleStep(DELAY_METER_RATIO / m_sample);
    meterSpinBox->setDecimals(DELAY_DECIMAL);
    meterSpinBox->setSuffix(tr(LABEL_METER_UINT));

    footSpinBox->setRange(DELAY_MIN * DELAY_FOOT_RATIO, max * DELAY_FOOT_RATIO);
    footSpinBox->setSingleStep(DELAY_FOOT_RATIO / m_sample);
    footSpinBox->setDecimals(DELAY_DECIMAL);
    footSpinBox->setSuffix(tr(LABEL_FOOT_UINT));

    connect(slider, QOverload<int>::of(&QSlider::valueChanged), this, &DelayWidget::sliderChanged);

    connect(timeSpinBox, QOverload<double>::of(&ADoubleSpinBox::valueChanged), this, &DelayWidget::timeSpinBoxChanged);
    connect(meterSpinBox, QOverload<double>::of(&ADoubleSpinBox::valueChanged), this, &DelayWidget::meterSpinBoxChanged);
    connect(footSpinBox, QOverload<double>::of(&ADoubleSpinBox::valueChanged), this, &DelayWidget::footSpinBoxChanged);
}

void DelayWidget::set(uint16_t delay)
{
    blockSignals(true);
    slider->setValue(delay);
    blockSignals(false);
}

void DelayWidget::sliderChanged(const int &value)
{
    setBlockSignals(true);
    timeSpinBox->setValue(static_cast<double>(value) / m_sample);
    meterSpinBox->setValue(value * DELAY_METER_RATIO / m_sample);
    footSpinBox->setValue(value * DELAY_FOOT_RATIO / m_sample);
    setBlockSignals(false);
    emit delay(m_channel, value);
}

void DelayWidget::timeSpinBoxChanged(const double &value)
{
    setBlockSignals(true);
    slider->setValue(value * m_sample + 0.5);
    meterSpinBox->setValue(value * DELAY_METER_RATIO);
    footSpinBox->setValue(value * DELAY_FOOT_RATIO);
    setBlockSignals(false);
}

void DelayWidget::meterSpinBoxChanged(const double &value)
{
    setBlockSignals(true);
    slider->setValue(value * m_sample / DELAY_METER_RATIO + 0.5);
    timeSpinBox->setValue(value / DELAY_METER_RATIO);
    footSpinBox->setValue(value * DELAY_FOOT_RATIO / DELAY_METER_RATIO);
    setBlockSignals(false);
}

void DelayWidget::footSpinBoxChanged(const double &value)
{
    setBlockSignals(true);
    slider->setValue(value * m_sample / DELAY_FOOT_RATIO + 0.5);
    timeSpinBox->setValue(value / DELAY_FOOT_RATIO);
    meterSpinBox->setValue(value * DELAY_METER_RATIO / DELAY_FOOT_RATIO);
    setBlockSignals(false);
}

void DelayWidget::setBlockSignals(bool block)
{
    slider->blockSignals(block);
    timeSpinBox->blockSignals(block);
    meterSpinBox->blockSignals(block);
    footSpinBox->blockSignals(block);
}

